#include "Gui.h";

extern LiquidCrystal lcd;

extern Aquarium_Devices aquarium_devices;
extern Dosing_Pumps            dosing_pumps;
extern Clock                              clock;
extern Temp                                 temp;
extern Gui                                    gui;
extern Aquarium_Modes      aquarium_modes;
extern Auto_Top                       auto_top;
extern Alerts                            alerts;

const byte MAIN_MENU_LEN = 7;

prog_char main_menu_0[] PROGMEM = "General Settings";
prog_char main_menu_1[] PROGMEM = "Dosing Pumps";
prog_char main_menu_2[] PROGMEM = "Devices Setting";
prog_char main_menu_3[] PROGMEM = "Modes Setting";
prog_char main_menu_4[] PROGMEM = "Auto Top-Off System";
prog_char main_menu_5[] PROGMEM = "Alerts";
prog_char main_menu_6[] PROGMEM = "HW Reset";

PROGMEM const char *main_menu_table[] = 
{   
  main_menu_0,
  main_menu_1,
  main_menu_2,
  main_menu_3,
  main_menu_4,
  main_menu_5,
  main_menu_6
};




const byte GENERAL_SETTING_LEN = 3;
prog_char General_Settings_0[] PROGMEM = "Clock Set";
prog_char General_Settings_1[] PROGMEM = "Date Set";
prog_char General_Settings_2[] PROGMEM = "Temp Calibration";
PROGMEM const char *General_Settings_table[] = 
{   
  General_Settings_0,
  General_Settings_1 ,
  General_Settings_2 
};

const byte ClOCK_SET_LEN = 3;
prog_char Clock_Set_0[] PROGMEM = "1.HR+ 2.MIN+ 3.SEC+";
prog_char Clock_Set_1[] PROGMEM = "4.HR- 5.MIN- 6.SEC-";
prog_char Clock_Set_2[] PROGMEM = "*.EXIT&SAVE   #.EXIT";

PROGMEM const char *Clock_Set_table[] = 
{   
  Clock_Set_0,
  Clock_Set_1 ,
  Clock_Set_2
};

const byte DATE_SET_LEN = 3;
prog_char Date_Set_0[] PROGMEM = "1.D+ 2.M+ 3.YR+ A.D+";
prog_char Date_Set_1[] PROGMEM = "4.D- 5.M- 6.YR- B.D+";
prog_char Date_Set_2[] PROGMEM = "*.EXIT&SAVE   #.EXIT";

PROGMEM const char *Date_Set_table[] = 
{   
  Date_Set_0,
  Date_Set_1 ,
  Date_Set_2
};

const byte DOSING_PUMP_MENU_LEN = 4;
prog_char Dosing_Pump_menu_0[] PROGMEM = "General Settings";
prog_char Dosing_Pump_menu_1[] PROGMEM = "Dosing Programs";
prog_char Dosing_Pump_menu_2[] PROGMEM = "One Time";
prog_char Dosing_Pump_menu_3[] PROGMEM = "Status";

PROGMEM const char *Dosing_Pump_Menu_table[] = 
{   
  Dosing_Pump_menu_0,
  Dosing_Pump_menu_1,
  Dosing_Pump_menu_2,
  Dosing_Pump_menu_3
};

prog_char Auto_Top_menu_0[] PROGMEM = "Auto Top-Off : ";
prog_char Auto_Top_menu_1[] PROGMEM = "Max On Time ";
prog_char Auto_Top_menu_2[] PROGMEM = "sec";
prog_char Auto_Top_menu_3[] PROGMEM = "Number In Day ";
prog_char Auto_Top_menu_4[] PROGMEM ="Status:";
prog_char Auto_Top_menu_5[] PROGMEM =" Pump Status: ";
prog_char Auto_Top_menu_6[] PROGMEM =" Turn On Today ";
prog_char Auto_Top_menu_7[] PROGMEM ="No Alerts ";
prog_char Auto_Top_menu_8[] PROGMEM ="Clear Alerts ";
prog_char Auto_Top_menu_9[] PROGMEM ="  Save Auto Top ";


PROGMEM const char *Auto_Top_Menu_table[] = 
{   
  Auto_Top_menu_0,
  Auto_Top_menu_1,
  Auto_Top_menu_2,
  Auto_Top_menu_3,
  Auto_Top_menu_4,
  Auto_Top_menu_5,
  Auto_Top_menu_6,
  Auto_Top_menu_7,
  Auto_Top_menu_8,
  Auto_Top_menu_9
};


prog_char Mode_Set_menu_0[] PROGMEM = "Auto Move : ";
prog_char Mode_Set_menu_1[] PROGMEM = " After : ";
prog_char Mode_Set_menu_2[] PROGMEM = " Min";
prog_char Mode_Set_menu_3[] PROGMEM = " To : ";
prog_char Mode_Set_menu_4[] PROGMEM = "Save Mode?";
prog_char Mode_Set_menu_5[] PROGMEM = "Timer ";
prog_char Mode_Set_menu_6[] PROGMEM = " Mode :";
prog_char Mode_Set_menu_7[] PROGMEM = " Time : ";
prog_char Mode_Set_menu_8[] PROGMEM = " Days:";




PROGMEM const char *Mode_Set_Menu_table[] = 
{   
  Mode_Set_menu_0,
  Mode_Set_menu_1,
  Mode_Set_menu_2,
  Mode_Set_menu_3,
  Mode_Set_menu_4,
  Mode_Set_menu_5,
  Mode_Set_menu_6,
  Mode_Set_menu_7,
  Mode_Set_menu_8
};




void Gui::Update(){
  switch (gui_state) {
  case  eIDLE:
    Idle_Print();
    break;
  case eTEMP_CALIBRATION:
    Temp_Calibration_Print();
    break;
  case eAUTO_TOP:
    Print_Auto_Top( );
    break;
  }   
}  

void Gui::Key_Press(char Key,bool hold){
  switch (gui_state) {
  case  eIDLE:
    Key_Press_Idel(Key);
    break;
  case eMAIN_MENU:
    Key_Press_Main_Menu(Key);
    break;
  case eGENERAL_SETTING:
    Key_Press_General_Settings(Key);
    break;
  case eDOSING_PUMPS:
    Key_Press_Dosing_Pumps(Key);
    break;  
  case eDEVICES:
    Key_Press_Devices(Key);
    break;
  case eMODES_SETTING:
    Key_Press_Modes_setting(Key);
    break;
  case eClOCK_SET:
    Key_Press_Clock_Set(Key);
    break;
  case eDATE_SET:
    Key_Press_Date_Set(Key);
    break;
  case eTEMP_CALIBRATION_SELECT:
    Key_Press_Temp_Calibration_Select(Key);
    break;
  case eTEMP_CALIBRATION:
    Key_Press_Temp_Calibration(Key);
    break;  
  case eDOSING_PUMP_MENU:
    Key_Press_Dosing_Pump_Menu(Key);
    break;  
  case eDOSING_PUMP_GEN:
    Key_Press_Dosing_Pump(Key);
    break;  
  case eDOSING_PUMP_CALIBRATION:
    Key_Press_Dosing_Pump(Key);
    break;  
  case eDOSING_PUMP_SET:
    Key_Press_Dosing_Pump(Key);
    break;  
  case eDOSING_PUMP_ONE_TIME:
    Key_Press_Dosing_Pump_One_Time(Key);
    break;  
  case eDOSING_PUMP_STATUS:
    Key_Press_Dosing_Pump(Key);
    break;  
  case eDEVICE_SET:
    Key_Press_Device_Set(Key);
    break;  
  case eMODE_SET:
    Key_Press_Mode_Set(Key);
    break;  
  case eAUTO_TOP:
    Key_Press_Auto_Top(Key);
    break;  
  case eALERTS:
    Key_Press_Alerts(Key);
    break;  
  }   
  lcd.clear();
  Print();
}

void Gui::Key_Press_Main_Up_Down(char Key, byte Menu_Len ,  byte Display_Num_Line ){
  if(   Key == '2' ) { // UP
    day_index = 1;
    if (  y_position > 0 ) 
      -- y_position;
    if (   y_position < y_offset )
      --y_offset;
  }
  if (  Key ==  '8' ) {// DOWN
    day_index = 1;
    if (  y_position < (Menu_Len-1)  ) {
      ++ y_position;
    }
    if (   y_position >= (y_offset+Display_Num_Line) ){
      ++y_offset;
    }
  }

}


void Gui::Key_Press_Idel(char  Key){
  if ( MoveToModeAsk){
    if ( Key == '*' ){
      aquarium_modes.MoveToMode(ModeNum);
      MoveToModeAsk = false;
    }
    if ( Key == '#' ){
      MoveToModeAsk = false;
    }    
  } 
  else{
    switch (Key) {
    case  '1':
      ModeNum = 0;
      MoveToModeAsk = true;
      break;
    case  '2':
      ModeNum = 1;
      MoveToModeAsk = true;
      break;
    case  '3':
      ModeNum = 2;
      MoveToModeAsk = true;
      break;
    case  '4':
      ModeNum = 3;
      MoveToModeAsk = true;
      break;
    case  '5':
      ModeNum = 4;
      MoveToModeAsk = true;
      break;
    case  '6':
      ModeNum = 5;
      MoveToModeAsk = true;
      break;
    case  '7':
      ModeNum = 6;
      MoveToModeAsk = true;
      break;
    case  '8':
      ModeNum = 7;
      MoveToModeAsk = true;
      break;
    default:
      Goto_Main_Menu();
      break;
    }  
  }

}

void Gui::Key_Press_Main_Menu(char Key){
  if ( Reset_ask ){
    if ( Key == '1' ){
      Reset_Memory();
      Reset_ask = false;
    }
    if ( Key == '3' ){
      Reset_ask = false;
    }    
  }
  else {
    Key_Press_Main_Up_Down(Key,MAIN_MENU_LEN,LCD_LINES);
    switch (Key) {
    case  '5'://Enter
      switch (y_position) {
      case 0:
        Goto_General_Settings();
        break;
      case 1:
        Goto_Dosing_Pumps();
        break;      
      case 2:
        Goto_Devices();
        break;
      case 3:
        Goto_Modes_setting();
        break;
      case 4:
        Goto_Auto_Top();
        break;
      case 5:
        Goto_Alerts();
        break;
      case 6:
        Reset_ask = true;
        break;
      }
      break;
    case  '#':// Back
      Goto_Idle();
      break;
    }   
  }
}

void Gui::Key_Press_General_Settings(char Key){
  Key_Press_Main_Up_Down(Key,GENERAL_SETTING_LEN,LCD_LINES);
  switch (Key) {
  case  '5'://Enter
    switch (y_position) {
    case 0:
      Goto_Clock_Set();
      break;
    case 1:
      Goto_Date_Set();
      break;
    case 2:
      Goto_Temp_Calibration_Select();
      break;
    }
    break;
  case  '#':// Back
    Goto_Main_Menu();
    break;
  }   
}

void Gui::Key_Press_Dosing_Pumps(char Key){
  Key_Press_Main_Up_Down(Key,NUMBER_OF_DOSING_PUMPS,LCD_LINES);
  switch (Key) {
  case  '5'://Enter
    Dosing_Pump_Num = y_position;
    Goto_Dosing_Pump_Menu();
    break;
  case  '#':// Back
    Goto_Main_Menu();
    break;
  }   
}
void Gui::Key_Press_Devices(char Key){
  Key_Press_Main_Up_Down(Key,NUMBER_OF_DEVICES,LCD_LINES);
  switch (Key) {
  case  '5'://Enter
    Goto_Device_Set();
    break;
  case  '#':// Back
    Goto_Main_Menu();
    break;
  }   
}

void Gui::Key_Press_Modes_setting(char Key){
  Key_Press_Main_Up_Down(Key,NUMBER_OF_MODES,LCD_LINES);
  switch (Key) {
  case  '5'://Enter
    Goto_Mode_Set();
    break;
  case  '#':// Back
    Goto_Main_Menu();
    break;
  }   
}

void Gui::Key_Press_Auto_Top(char Key){
  if ( Auto_Top_Save_Ask ){
    if ( Key == '1' ){
      auto_top.Set_Max_On_Time(  Auto_Top_Max_On_Time   ); // in sec
      auto_top.Set_Max_Number_Of_Time_In_Day(   Auto_Top_Max_Number_Of_Time_In_Day  );
      auto_top.Set_Modes(Auto_Top_Modes);
      auto_top.Set_OnOff(Auto_Top_OnOff);
      auto_top.Save_To_EEPROM();
      Goto_Main_Menu();
    }
    if ( Key == '3' ){
      Auto_Top_Save_Ask = false;
    }

  }
  else {
    Key_Press_Main_Up_Down(Key,NUMBER_OF_MODES+7,LCD_LINES);
    switch (Key) {
    case '4':
      if ( y_position == 0 ) {
        Auto_Top_OnOff = false;
      }
      if ( y_position == 1 ) {
        if ( Auto_Top_Max_On_Time > 0 ) {
          --Auto_Top_Max_On_Time;
        }
      }
      if ( y_position == 2 ) {
        if ( Auto_Top_Max_Number_Of_Time_In_Day  > 0 ){
          --Auto_Top_Max_Number_Of_Time_In_Day;
        }
      }
      if ( y_position > 2  &&  ( y_position < (NUMBER_OF_MODES+3 ))    ) {
        bitWrite(Auto_Top_Modes,y_position-3,0 ) ;
      }
      break;
    case '6':
      if ( y_position == 0 ) {
        Auto_Top_OnOff = true;
      }
      if ( y_position == 1 ) {
        if ( Auto_Top_Max_On_Time < 10000 ) {
          ++Auto_Top_Max_On_Time;
        }
      }
      if ( y_position == 2 ) {
        if ( Auto_Top_Max_Number_Of_Time_In_Day  < 256 ){
          ++Auto_Top_Max_Number_Of_Time_In_Day;
        }
      }
      if ( y_position > 2  &&  ( y_position < (NUMBER_OF_MODES+3 ))    ) {
        bitWrite(Auto_Top_Modes,y_position-3,1 ) ;
      }
      break;
    case '1':
      if ( y_position == 1 ) {
        if ( Auto_Top_Max_On_Time > 10 ) {
          Auto_Top_Max_On_Time -=10;
        }
      }
      if ( y_position == 2 ) {
        if ( Auto_Top_Max_Number_Of_Time_In_Day  > 10 ){
          Auto_Top_Max_Number_Of_Time_In_Day-=10;
        }
      }
      break;
    case '3':
      if ( y_position == 1 ) {
        if ( Auto_Top_Max_On_Time < 9990 ) {
          Auto_Top_Max_On_Time+=10;
        }
      }
      if ( y_position == 2 ) {
        if ( Auto_Top_Max_Number_Of_Time_In_Day  < 246 ){
          Auto_Top_Max_Number_Of_Time_In_Day +=10;
        }
      }
      break;
    case '5' :
      if ( y_position == (NUMBER_OF_MODES+6) && auto_top.Is_There_Error()  ){
        auto_top.Clear_Errors();
      }
      break;
    case  '*'://Save&Exit
      Auto_Top_Save_Ask = true;
      break;  
    case  '#':// Back
      Goto_Main_Menu();
      break;
    }   
  }
}

void Gui::Key_Press_Alerts(char Key){
  Key_Press_Main_Up_Down(Key,Number_of_Print_Alerts_Lines,LCD_LINES-1);
  switch (Key) {
  case  '*'://Enter
    Number_of_Print_Alerts_Lines = alerts.Clear_Alert(y_position);
    y_position = 0;
    y_offset = 0;
    break;
  case  '#':// Back
    Goto_Main_Menu();
    break;
  }   
}

void Gui::Key_Press_Dosing_Pump_Menu(char Key){
  Key_Press_Main_Up_Down(Key,DOSING_PUMP_MENU_LEN,LCD_LINES-1);
  switch (Key) {
  case  '5'://Enter
    switch (y_position) {
    case 0:
      Goto_Dosing_Pump_Gen();
      break;
    case 1:
      Goto_Dosing_Pump_Set();
      break;      
    case 2:
      Goto_Dosing_Pump_One_Time();
      break;
    case 3:
      Goto_Dosing_Pump_Status();
      break;
    }
    break;
  case  '#':// Back
    Goto_Dosing_Pumps();
    break;
  }   
}

void  Gui::Key_Press_Dosing_Pump(char Key){
  if ( gui_state == eDOSING_PUMP_STATUS ){
    if ( Clear_History_Ask ){
      if ( Key == '1') { // Yes
        dosing_pumps.Clear_History(Dosing_Pump_Num);
        Goto_Dosing_Pump_Menu();
      }
      if ( Key == '3' ){ // No
        Clear_History_Ask = false;
      }  
    }
    if ( Key == '5'){
      Clear_History_Ask = true;
    }

    if ( Key == '#'){
      Goto_Dosing_Pump_Menu();
    }
  } 
  else if ( gui_state == eDOSING_PUMP_CALIBRATION ){
    if ( Key == '5'){
      dosing_pumps.End_Pump_Calibration(Dosing_Pump_Num);
      Temp_dosing_pump = dosing_pumps.Get_Dosing_Pump(Dosing_Pump_Num);
      Goto_Dosing_Pump_Gen();      
    }    
  }  
  else {
    if ( gui_state == eDOSING_PUMP_GEN ){
      Key_Press_Main_Up_Down(Key,DOSING_PUMP_GEN_NUMBER_OF_LINE,LCD_LINES);
      if ( Temp_dosing_pump.Key_Prass_Gen( y_position,Key) ){
        gui_state = eDOSING_PUMP_CALIBRATION;        
        dosing_pumps.Start_Pump_Calibration(Dosing_Pump_Num);
      }
    }
    if ( gui_state == eDOSING_PUMP_SET ){
      Key_Press_Main_Up_Down(Key,DOSING_PUMP_SET_NUMBER_OF_LINE,LCD_LINES);
      Temp_dosing_pump.Key_Prass_Set( y_position,Key);
    }

    switch (Key) {
    case  '*':// Back&Save
      dosing_pumps.Set_Dosing_Pump(Dosing_Pump_Num , Temp_dosing_pump);
      //  break; // break need needed here  
    case  '#':// Back
      Goto_Dosing_Pump_Menu();
      break;
    }
  }
}

void  Gui::Key_Press_Dosing_Pump_One_Time(char Key){
  if ( One_Time_Ask ){
    if ( Key == '1') { // Yes
      byte _Stirrer_Time = (Stirrer_Time == 0) ? 0 : Stirrer_Time+1;
      dosing_pumps.Start(Dosing_Pump_Num,_Stirrer_Time , Pump_Liquid_Amount_l ,  Pump_Liquid_Amount_h);
      Goto_Dosing_Pump_Menu();
    }
    if ( Key == '3' ){ // No
      One_Time_Ask = false;
    }  
  }
  else {
    Key_Press_Main_Up_Down(Key,2,LCD_LINES);
    switch (Key) {
    case '4':
      if ( y_position == 0 ) {
        --Stirrer_Time;
      }
      if ( y_position == 1 ) {
        if ( Pump_Liquid_Amount_l  != 0 ){
          Pump_Liquid_Amount_l -= 10;
        }
        else if ( Pump_Liquid_Amount_h > 0 ){
          Pump_Liquid_Amount_l = 90;
          --Pump_Liquid_Amount_h;
        }
      }
      break;
    case '6':
      if ( y_position == 0 ) {
        Stirrer_Time++;
      }
      if ( y_position == 1 ) {
        if ( Pump_Liquid_Amount_l  < 90 ){
          Pump_Liquid_Amount_l += 10;
        }
        else{
          Pump_Liquid_Amount_l = 0;
          ++Pump_Liquid_Amount_h;
        }
      }
      break;
    case '1':
      if ( y_position == 0 ) {
        Stirrer_Time -= 10;
      }
      if ( y_position == 1 ) {
        if ( Pump_Liquid_Amount_h > 0 ){
          --Pump_Liquid_Amount_h;
        }      
      }
      break;
    case '3':
      if ( y_position == 0 ) {
        Stirrer_Time += 10;
      }
      if ( y_position == 1 ) {
        ++Pump_Liquid_Amount_h;
      }
      break;
    case  '*':// Back&Save
      One_Time_Ask = true;
      break; 
    case  '#':// Back
      Goto_Dosing_Pump_Menu();
      break;
    }
  }
}

void Gui::Key_Press_Device_Set(char Key){
  Key_Press_Main_Up_Down(Key,DEVICE_PRINT_NUMBER_OF_LINE,LCD_LINES-1);
  Temp_Aquarium_Device.Key_Prass( y_position,Key);
  switch (Key) {
  case  '*':// Back&Save
    aquarium_devices.Set_Aquarium_Device(Device_Num , Temp_Aquarium_Device);
    //  break; // break need needed here  
  case  '#':// Back
    Goto_Devices();
    break;
  }   
}


void Gui::Key_Press_Mode_Set(char Key){
  Key_Press_Main_Up_Down(Key,3+(4 *MODES_NUMBER_OF_TIMERS),LCD_LINES-1);
  if (  Mode_SetAsk ){
    if ( Key == '1') { // Yes
      aquarium_modes.SetMoveTo( Mode_Set_Num,Mode_MoveTo);
      aquarium_modes.SetMoveToAfter(Mode_Set_Num, Mode_MoveToAfter);
      for ( int i ; i < MODES_NUMBER_OF_TIMERS ; ++i ){
        aquarium_modes.SetTimer_On(Mode_Set_Num, i, Mode_Timer_On[i] );
        aquarium_modes.SetTimer_HR(Mode_Set_Num, i,Mode_Timer_HR[i]);
        aquarium_modes.SetTimer_MIN(Mode_Set_Num, i,Mode_Timer_MIN[i]);
        aquarium_modes.SetTimer_DAY(Mode_Set_Num, i,Mode_Timer_DAY[i]);
        aquarium_modes.SetTimer_MoveTo(Mode_Set_Num, i, Mode_Timer_MoveTo[i] );
      }

      aquarium_modes.Save_To_EEPROM();
      Goto_Modes_setting();
    }
    if ( Key == '3' ){ // No
      Mode_SetAsk = false;
    }  
  } 
  else {
    switch (Key) {
    case '1':
      if ( (  y_position  > 2) &&  ( y_position  < 3 + (4 *MODES_NUMBER_OF_TIMERS)  ) ){
        byte timer = (y_position - 3)  / 4 ;
        byte offset = (y_position - 3)  % 4 ;

        if ( offset == 1 ) {
          if ( Mode_Timer_HR[timer] == 0 ) {
            Mode_Timer_HR[timer] = 23;
          }
          else {
            --Mode_Timer_HR[timer];
          }
        }
      }
      break;
    case '3':
      if ( (  y_position  > 2) &&  ( y_position  < 3 + (4 *MODES_NUMBER_OF_TIMERS)  ) ){
        byte timer = (y_position - 3)  / 4 ;
        byte offset = (y_position - 3)  % 4 ;

        if ( offset == 1 ) {
          if ( Mode_Timer_HR[timer] == 23 ) {
            Mode_Timer_HR[timer] = 0;
          }
          else {
            ++Mode_Timer_HR[timer];
          }
        }
      }
      break;
    case '4':
      if ( y_position == 1 ) {
        --Mode_MoveToAfter;
      }
      if ( y_position == 2 ) {
        if ( Mode_MoveTo > 0  ){
          --Mode_MoveTo;
        }        
      }
      if ( (  y_position  > 2) &&  ( y_position  < 3 + (4 *MODES_NUMBER_OF_TIMERS)  ) ){
        byte timer = (y_position - 3)  / 4 ;
        byte offset = (y_position - 3)  % 4 ;

        if (offset == 0 ){
          Mode_Timer_On[timer] = false;
        }
        if ( offset == 1 ) {
          if ( Mode_Timer_MIN[timer] == 0 ) {
            Mode_Timer_MIN[timer] = 59;
          }
          else {
            --Mode_Timer_MIN[timer];
          }
        }
        if ( offset == 2) {
          bitWrite(Mode_Timer_DAY[timer], day_index,  !bitRead(Mode_Timer_DAY[timer] , day_index )  );   
        }
        if ( offset == 3) {
          if ( Mode_Timer_MoveTo[timer] > 0 ) {
            --Mode_Timer_MoveTo[timer];
          }
        }
      }
      break;
    case '6':
      if ( y_position == 1 ) {
        ++Mode_MoveToAfter;
      }
      if ( y_position == 2 ) {
        if ( Mode_MoveTo  < (NUMBER_OF_MODES-1) ){
          ++Mode_MoveTo;
        }
      }
      if ( (  y_position  > 2) &&  ( y_position  < 3 + (4 *MODES_NUMBER_OF_TIMERS)  ) ){
        byte timer = (y_position - 3)  / 4 ;
        byte offset = (y_position - 3)  % 4 ;

        if (offset == 0 ){
          Mode_Timer_On[timer] = true;
        }
        if ( offset == 1 ) {
          if ( Mode_Timer_MIN[timer] == 59 ) {
            Mode_Timer_MIN[timer] = 0;
          }
          else {
            ++Mode_Timer_MIN[timer];
          }
        }
        if (offset == 2){
          if (day_index < 7 ){
            ++day_index;
          } 
          else {
            day_index = 1;
          }
        }
        if ( offset == 3 ) {
          if ( Mode_Timer_MoveTo[timer] < (NUMBER_OF_MODES-1)  ) {
            ++Mode_Timer_MoveTo[timer];
          }
        }
      }
      break;
    case  '*':// Back&Save 
      Mode_SetAsk = true;
      break; // break need needed here  
    case  '#':// Back
      Goto_Modes_setting();
      break;
    }   
  }
}

void Gui::Key_Press_Clock_Set(char Key){
  switch (Key) {
  case  '1':// HR+
    hr = (hr + 1) %24;
    break;
  case  '2':// min+
    min = (min + 1)%60;
    break;
  case  '3'://sec+
    sec = (sec + 1 )%60;
    break;
  case  '4'://HR-
    if ( hr == 0 ) {
      hr = 23;
    }
    else{
      --hr;
    }
    break;
  case  '5':// MIN-
    if ( min == 0 ) {
      min = 59;
    } 
    else { 
      --min;
    }
    break;
  case  '6':// SEC-
    if ( sec == 0 ) {
      sec = 59;
    } 
    else { 
      --sec;
    }
    break;
  case  '*':// Back&Save
    clock.set_time(hr,min,sec);
    //  break; // break need needed here
  case  '#':// Back
    Goto_General_Settings();
    break;
  }   
}


void Gui::Key_Press_Date_Set(char Key){
  prog_char Date_Set_0[] PROGMEM = "1.YR+ 2.M+ 3.+ A.D+";
  prog_char Date_Set_1[] PROGMEM = "4.YR- 5.M- 6.D- B.D+";

  switch (Key) {
  case  '1':// DATE+
    if ( date == 31 ) {
      date = 1;
    }
    else {
      ++date;
    }
    break;
  case  '2':// MTH+
    if ( mth == 12 ) {
      mth = 1;
    }
    else {
      ++mth;
    }
    break;
  case  '3'://YR+
    ++yr;
    break;
  case  'A'://day+
    if ( day == 7 ) {
      day = 1;
    }
    else {
      ++day;
    }
    break;
  case  '4'://DATE-
    if ( date == 1 ) {
      date = 31;
    } 
    else { 
      --date;
    }
    break;
  case  '5':// MTH-
    if ( mth == 1 ) {
      mth = 12;
    } 
    else { 
      --mth;
    }
    break;
  case  '6':// YR-
    --yr;
    break;
  case  'B':// day-
    if ( day == 1 ) {
      day = 7;
    } 
    else { 
      --day;
    }
    break;
  case  '*':// Back&Save
    clock.set_date(yr,mth,date,day);
    //  break; // break need needed here
  case  '#':// Back
    Goto_General_Settings();
    break;
  }   
}

void Gui::Key_Press_Temp_Calibration_Select(char Key){
  Key_Press_Main_Up_Down(Key,TEMP_NUMBER_OF_PROBES,LCD_LINES);
  switch (Key) {
  case  '5'://Enter
    Goto_Temp_Calibration();
    break;
  case  '#':// Back
    Goto_General_Settings();
    break;
  }   
}

void Gui::Key_Press_Temp_Calibration(char Key){
  switch (Key) {
  case  '4':// +
    if ( temp_calibration < 100 ){
      ++temp_calibration;
    }
    break; 
  case  '6':// -
    if ( temp_calibration > -100 ){
      --temp_calibration;
    }
    break; 
  case  '*':// Back&Save
    temp.set_temp_calibration(probe_num,temp_calibration);
    //  break; // break need needed here 
  case  '#':// Back
    Goto_Temp_Calibration_Select();
    break;
  }   
}

void Gui::Goto_Idle(){
  gui_state = eIDLE;
  MoveToModeAsk = false;
}

void Gui::Goto_Main_Menu(){
  gui_state = eMAIN_MENU;
  Reset_ask = false;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_General_Settings(){
  gui_state = eGENERAL_SETTING;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Dosing_Pumps(){
  gui_state = eDOSING_PUMPS;
  y_position = 0;
  y_offset = 0;
}
void Gui::Goto_Devices(){
  gui_state = eDEVICES;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Modes_setting(){
  gui_state = eMODES_SETTING;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Dosing_Pump_Menu(){
  gui_state = eDOSING_PUMP_MENU;
  y_position = 0;
  y_offset = 0;
  Temp_dosing_pump = dosing_pumps.Get_Dosing_Pump(Dosing_Pump_Num);
}

void Gui::Goto_Dosing_Pump_Gen(){
  gui_state = eDOSING_PUMP_GEN;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Dosing_Pump_Set(){
  gui_state = eDOSING_PUMP_SET;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Dosing_Pump_One_Time(){
  gui_state = eDOSING_PUMP_ONE_TIME;
  y_position = 0;
  y_offset = 0;
  Stirrer_Time = 0;
  Pump_Liquid_Amount_l = 0;
  Pump_Liquid_Amount_h = 0;
  One_Time_Ask = false;
}

void Gui::Goto_Dosing_Pump_Status(){
  gui_state = eDOSING_PUMP_STATUS;
  y_position = 0;
  y_offset = 0;
  Clear_History_Ask = false;
}

void Gui::Goto_Device_Set(){
  gui_state = eDEVICE_SET;
  Device_Num = y_position;
  Temp_Aquarium_Device = aquarium_devices.Get_Aquarium_Device(Device_Num);
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Mode_Set(){
  gui_state          = eMODE_SET;
  Mode_Set_Num = y_position;
  Mode_MoveTo               = aquarium_modes.GetMoveTo(Mode_Set_Num);
  Mode_MoveToAfter = aquarium_modes.GetMoveToAfter(Mode_Set_Num);
  for ( int i ; i < MODES_NUMBER_OF_TIMERS ; ++i ){
    Mode_Timer_On[i]            = aquarium_modes.GetTimer_On(Mode_Set_Num, i);
    Mode_Timer_HR[i]            = aquarium_modes.GetTimer_HR(Mode_Set_Num, i);
    Mode_Timer_MIN[i]         = aquarium_modes.GetTimer_MIN(Mode_Set_Num, i);
    Mode_Timer_DAY[i]         = aquarium_modes.GetTimer_DAY(Mode_Set_Num, i);
    Mode_Timer_MoveTo[i] = aquarium_modes.GetTimer_MoveTo(Mode_Set_Num, i);
  }




  Mode_SetAsk = false;
  y_position      = 0;
  y_offset            = 0;
}



void Gui:: Goto_Auto_Top(){
  gui_state = eAUTO_TOP;
  y_position = 0;
  y_offset = 0;
  Auto_Top_Save_Ask = false;
  Auto_Top_OnOff = auto_top.Get_OnOff();
  Auto_Top_Max_On_Time = auto_top.Get_Max_On_Time(); // in sec
  Auto_Top_Max_Number_Of_Time_In_Day = auto_top.Get_Max_Number_Of_Time_In_Day();
  Auto_Top_Modes = auto_top.Get_Modes();
}


void Gui::Goto_Alerts(){
  gui_state = eALERTS;
  y_position = 0;
  y_offset = 0;
  Number_of_Print_Alerts_Lines = alerts.Get_Number_Of_Print_Line();
}



void Gui::Goto_Clock_Set(){
  gui_state = eClOCK_SET;
  hr     = RTC.get(DS1307_HR,false);
  min   = RTC.get(DS1307_MIN,false);
  sec   = RTC.get(DS1307_SEC,false);
}

void Gui::Goto_Date_Set(){
  gui_state = eDATE_SET;
  yr       = RTC.get(DS1307_YR,false);
  mth     = RTC.get(DS1307_MTH,false);
  date  = RTC.get(DS1307_DATE,false);
  day     = RTC.get(DS1307_DOW,false);
}

void Gui::Goto_Temp_Calibration_Select(){
  gui_state = eTEMP_CALIBRATION_SELECT;
  y_position = 0;
  y_offset = 0;
}

void Gui::Goto_Temp_Calibration(){
  gui_state = eTEMP_CALIBRATION;
  probe_num = y_position;
  temp_calibration = temp.get_temp_calibration(probe_num);
}


void Gui::Print(){
  switch (gui_state) {
  case  eIDLE:
    Idle_Print();
    break;
  case eMAIN_MENU:
    Main_Menu_Print();
    break;
  case eGENERAL_SETTING:
    Menu_Print( General_Settings_table,GENERAL_SETTING_LEN,LCD_LINES,0 );
    break;
  case eDOSING_PUMPS:
    Menu_Print(dosing_pumps_name_table,NUMBER_OF_DOSING_PUMPS,LCD_LINES,0 );
    break;
  case eDEVICES:
    Menu_Print( device_name_table,NUMBER_OF_DEVICES,LCD_LINES,0 );
    break;
  case eMODES_SETTING:
    Menu_Print( modes_name_table,NUMBER_OF_MODES,LCD_LINES,0 );
    break;
  case eAUTO_TOP:
    Print_Auto_Top( );
    break;
  case eALERTS:
    Print_Alerts( );
    break;
  case eDOSING_PUMP_MENU:
    lcd.setCursor(0, 0);
    dosing_pumps.Print_Pump_Name(Dosing_Pump_Num);
    Print_Colon();
    Menu_Print( Dosing_Pump_Menu_table,DOSING_PUMP_MENU_LEN,LCD_LINES-1,1 );
    break;   
  case eDOSING_PUMP_GEN:
    Dosing_Pump_Print();
    break;
  case eDOSING_PUMP_CALIBRATION:
    Dosing_Pump_Print();
    break;
  case eDOSING_PUMP_SET:
    Dosing_Pump_Print();
    break;
  case eDOSING_PUMP_ONE_TIME:
    Dosing_Pump_One_Time_Print();
    break;
  case eDOSING_PUMP_STATUS:
    Dosing_Pump_Print();
    break;
  case eDEVICE_SET:
    Device_Set_Print();
    break;  
  case eMODE_SET:
    Mode_Set_Print();
    break;  
  case eClOCK_SET:
    Clock_Set_Print( );
    break;
  case eDATE_SET:
    Date_Set_Print( );
    break;    
  case eTEMP_CALIBRATION_SELECT:
    Menu_Print( temp_probes_name_table,TEMP_NUMBER_OF_PROBES,LCD_LINES,0 );
    break;    
  case eTEMP_CALIBRATION:
    Temp_Calibration_Print();
    break;    
  }   

}  

void Gui::Menu_Print(  const char **menu_table , byte menu_len , byte Display_Num_Line , byte Display_Offset ){
  for(byte i=0 ; (i < Display_Num_Line) && ( i <  menu_len )   ; ++i ){
    lcd.setCursor(0, i+Display_Offset);
    if (  y_position == (i+y_offset)  ){
      lcd.write('>');
    }
    else{
      lcd.write(' ');
    }
    strcpy_P(buffer, (char*)pgm_read_word(&(  menu_table[  i+y_offset ]     )));
    lcd.print(buffer );
  }
}

void Gui::Idle_Print(){
  if ( MoveToModeAsk){
    lcd.setCursor(0, 0);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  ARE_YOU_SURE_STRING ]     )));
    lcd.print(buffer );
    lcd.setCursor(0, 1);
    aquarium_modes.Print(ModeNum);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ MODE_STRING  ]     )));
    lcd.print(buffer );
    lcd.setCursor(0, 2);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ YES_NO_STRING_2  ]     )));
    lcd.print(buffer );
  }
  else{
    lcd.setCursor(0, 0);
    clock.print_day();
    lcd.print(" ");
    clock.print_date();
    lcd.setCursor(15, 0);
    clock.print_time_min();  
    lcd.setCursor(0, 1);

    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  TEMP_STRING ]     )));
    lcd.print(buffer );
    lcd.print(" : ");

    temp.print_temp( TEMP_AQUARIUM_PROBE );

    lcd.setCursor(0, 2);
    if ( alerts.Get_Number_OF_Alerts() == 0 ){
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  NO_ALERTS_STRING ]     )));
      lcd.print(buffer );
    }
    else{
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  ALERTS_STRING ]     )));
      lcd.print(buffer );
    }

    //strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  FREE_MEMORY_STRING ]     )));
    //lcd.print(buffer );
    //lcd.print(freeMemory());
    //clock.print_time_sec();  

    lcd.setCursor(0, 3);
    if( aquarium_modes.mode_change){
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ EMPTY_LINE]     )));
      lcd.print(buffer );     
      lcd.setCursor(0, 3);
      aquarium_modes.mode_change = false;
    }
    aquarium_modes.Print();
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ MODE_STRING  ]     )));
    lcd.print(buffer );
  }
}

void Gui::Main_Menu_Print(){
  if ( Reset_ask ){
    lcd.setCursor(0, 0);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  ARE_YOU_SURE_STRING ]     )));
    lcd.print(buffer );
    lcd.setCursor(0, 1);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ YES_NO_STRING  ]     )));
    lcd.print(buffer );
  } 
  else {
    Menu_Print( main_menu_table,MAIN_MENU_LEN,LCD_LINES,0 );
  }
}
void Gui::Dosing_Pump_Print(){
  if ( gui_state == eDOSING_PUMP_CALIBRATION){
    lcd.setCursor(0, 1);
    lcd.print("Prass 5 after ");
    lcd.print(DOSING_PUMP_CALIBRATION_AMOUNT);
    lcd.print("ml");
  }
  if ( gui_state == eDOSING_PUMP_GEN){
    for(byte i=0 ; i < (LCD_LINES) ; ++i ){
      lcd.setCursor(0, i);
      if (Temp_dosing_pump.Print_promt_Gen()){
        if (  y_position == (i+y_offset)  ){
          lcd.write('>');
        }
        else{
          Print_Space();
        }
      }
      Temp_dosing_pump.Print_Gen(i+y_offset);
    }
  }
  if ( gui_state == eDOSING_PUMP_SET){
    byte program_num = y_position / 4;
    for(byte i=0 ; i < (LCD_LINES) ; ++i ){
      lcd.setCursor(0, i);
      if (  y_position==  ((4*program_num)+i)  ){
        lcd.write('>');
      }
      else{
        Print_Space();
      }
      Temp_dosing_pump.Print_Set( (4*program_num)+i);
    }
  }
  if ( gui_state == eDOSING_PUMP_STATUS ){
    if ( Clear_History_Ask ){
      lcd.setCursor(0, 0);
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  ARE_YOU_SURE_STRING ]     )));
      lcd.print(buffer );
      lcd.setCursor(0, 1);
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ YES_NO_STRING  ]     )));
      lcd.print(buffer );
    }
    else{
      lcd.setCursor(0, 0);
      dosing_pumps.Print_History(Dosing_Pump_Num);
      lcd.setCursor(0, 1);
      dosing_pumps.Print_Last_Time(Dosing_Pump_Num);
      lcd.setCursor(0, 2);
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ Prass_5_STRING  ]     )));
      lcd.print(buffer );
      lcd.setCursor(0, 3);
      strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ Clear_History_STRING  ]     )));
      lcd.print(buffer );
    }
  }

}

void Gui::Dosing_Pump_One_Time_Print(){
  if ( One_Time_Ask ){
    lcd.setCursor(0, 0);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  ARE_YOU_SURE_STRING ]     )));
    lcd.print(buffer );
    lcd.setCursor(0, 1);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  STIRRER_TIME_STRING ]     )));
    lcd.print(buffer );
    if ( Stirrer_Time ==  0 ){
      Print_OFF();
    } 
    else {
      lcd.print((int)Stirrer_Time);
    }  
    lcd.setCursor(0, 2);
    Temp_dosing_pump.Print_Liquid(Pump_Liquid_Amount_l , Pump_Liquid_Amount_h);
    lcd.setCursor(0, 3);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[ YES_NO_STRING  ]     )));
    lcd.print(buffer );
  }
  else {
    for(byte i=0 ; i < 2 ; ++i ){
      lcd.setCursor(0, i);
      if (  y_position == (i+y_offset)  ){
        lcd.write('>');
      }
      else{
        Print_Space();
      }

      if ( i == 0){
        strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  STIRRER_TIME_STRING ]     )));
        lcd.print(buffer );
        if ( Stirrer_Time ==  0 ){
          Print_OFF();
        } 
        else {
          lcd.print((int)Stirrer_Time);
        }  
      }
      if ( i == 1){
        Temp_dosing_pump.Print_Liquid(Pump_Liquid_Amount_l , Pump_Liquid_Amount_h);
      }
    }
  }
}

void Gui::Device_Set_Print(){
  lcd.setCursor(0, 0);
  strcpy_P(buffer, (char*)pgm_read_word(&(   device_name_table[ Device_Num ]     )));
  lcd.print(buffer );
  lcd.print(":");

  for(byte i=0 ; i < (LCD_LINES-1) ; ++i ){
    lcd.setCursor(0, i+1);
    if (  y_position == (i+y_offset)  ){
      lcd.write('>');
    }
    else{
      Print_Space();
    }
    Temp_Aquarium_Device.Print(i+y_offset);
  }
}

void Gui::Clock_Set_Print( ){
  lcd.setCursor(0, 0);
  clock.print_time(hr ,  min ,  sec);  

  for(byte i = 0 ; i <  ClOCK_SET_LEN ; ++i){

    lcd.setCursor(0, i+1);
    strcpy_P(buffer, (char*)pgm_read_word(&(  Clock_Set_table[  i ]     )));
    lcd.print(buffer );
  }
}

void Gui::Date_Set_Print( ){
  lcd.setCursor(0, 0);
  clock.print_date(yr , mth , date , day);  

  for(byte i = 0 ; i <  DATE_SET_LEN ; ++i){
    lcd.setCursor(0, i+1);
    strcpy_P(buffer, (char*)pgm_read_word(&(  Date_Set_table[  i ]     )));
    lcd.print(buffer );
  }
}

void Gui::Temp_Calibration_Print(){
  lcd.setCursor(0, 0);
  temp.print_probe_name(probe_num);
  lcd.setCursor(0, 1);
  strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  PROBE_STRING ]     )));
  lcd.print(buffer );
  Print_Space();
  strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  Temp_STRING ]     )));
  lcd.print(buffer );
  Print_Space(); // " : "
  Print_Colon();
  Print_Space();
  temp.print_temp_without_calibration(probe_num );
  lcd.setCursor(0,2);
  strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  Temp_STRING ]     )));
  lcd.print(buffer );
  Print_Space(); // " : "
  Print_Colon();
  Print_Space();
  temp.print_temp(probe_num,temp_calibration);
  lcd.setCursor(0,3);
  strcpy_P(buffer, (char*)pgm_read_word(&(  Date_Set_table[  2 ]     )));
  lcd.print(buffer );

}

void Gui::Print_Auto_Top( ){
  if ( Auto_Top_Save_Ask){
    lcd.setCursor(0, 1);
    strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  9 ]     )));
    lcd.print(buffer );
    lcd.setCursor(0, 2);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  YES_NO_STRING ]     )));
    lcd.print(buffer );    
  } 
  else {
    for(byte i=0 ; i < (LCD_LINES) ; ++i ){
      lcd.setCursor(0, i);
      if (  y_position == (i+y_offset)  ){
        lcd.write('>');
      }
      else{
        Print_Space();
      }
      if ( i+y_offset == 0 ){
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  0 ]     )));
        lcd.print(buffer );
        if (Auto_Top_OnOff){
          Print_ON();
        } 
        else{
          Print_OFF();
        }
      } 
      else if ( i+y_offset == 1 ){
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  1 ]     )));
        lcd.print(buffer );
        lcd.print((int)Auto_Top_Max_On_Time);
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  2 ]     )));
        lcd.print(buffer );
      } 
      else if (i+y_offset == 2) {
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  3 ]     )));
        lcd.print(buffer );
        lcd.print((int)Auto_Top_Max_Number_Of_Time_In_Day);
      } 
      else if (   (i+y_offset-3) < NUMBER_OF_MODES) {   
        byte mode =    i+y_offset - 3;
        aquarium_modes.Print(mode);
        lcd.print(" : ");
        if ( bitRead(Auto_Top_Modes,mode )   ){
          Print_ON();
        } 
        else {
          Print_OFF();
        }      
      } 
      else if ( (i+y_offset) ==(NUMBER_OF_MODES+3) ){
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  4  ]     )));
        lcd.print(buffer );
      } 
      else if (   (i+y_offset) ==(NUMBER_OF_MODES+4)   ) {
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  5  ]     )));
        lcd.print(buffer );
        if ( auto_top.Is_Pump_On() ){
          Print_ON();
        } 
        else {
          Print_OFF();
        }
      }
      else if (   (i+y_offset) ==(NUMBER_OF_MODES+5)   ) {
        strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  6  ]     )));
        lcd.print(buffer );
        lcd.print((int) auto_top.Get_Number_Of_Time_Pump_On_Today() ) ;
      }
      else if (   (i+y_offset) ==(NUMBER_OF_MODES+6)   )   {
        if ( auto_top.Is_There_Error()  ){
          strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  8  ]     )));
          lcd.print(buffer );
        } 
        else {
          strcpy_P(buffer, (char*)pgm_read_word(&(  Auto_Top_Menu_table[  7  ]     )));
          lcd.print(buffer );
        }
      }
    }
  }
}

void Gui::Print_Alerts( ){
  lcd.setCursor(0, 0);
  lcd.print("Alerts:");
  for(byte i=0 ; (i < 3 ) && ( i <  Number_of_Print_Alerts_Lines )   ; ++i ){
    lcd.setCursor(0, i+1);
    if (  y_position == (i+y_offset)  ){
      lcd.write('>');
    }
    else{
      Print_Space();
    }
    alerts.Print(i+y_offset);
  }  
}


void Gui::Mode_Set_Print(){
  if ( Mode_SetAsk){
    lcd.setCursor(0, 1);
    strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  4 ]     )));
    lcd.print(buffer );
    lcd.setCursor(0, 2);
    strcpy_P(buffer, (char*)pgm_read_word(&(  gen_string_table[  YES_NO_STRING ]     )));
    lcd.print(buffer );    
  }  
  else   {
    lcd.setCursor(0, 0);
    aquarium_modes.Print( Mode_Set_Num  );
    for(byte i=0 ; i < (LCD_LINES-1) ; ++i ){
      lcd.setCursor(0, i+1);
      if (  y_position == (i+y_offset)  ){
        lcd.write('>');
      }
      else{
        Print_Space();
      }
      if (  (i+y_offset)  == 0 ){
        strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  0  ]     )));
        lcd.print(buffer );
      } 
      else if  (  (i+y_offset)  == 1 ){
        strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  1  ]     )));
        lcd.print(buffer );
        if (  Mode_MoveToAfter == 0 ){
          Print_OFF();
        }  
        else {
          lcd.print((int)  Mode_MoveToAfter  );
          strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  2  ]     )));
          lcd.print(buffer );
        }
      }  
      else if  (  (i+y_offset)  == 2 ){
        strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  3 ]     )));
        lcd.print(buffer );
        aquarium_modes.Print( Mode_MoveTo  );
      }
      else if ( ((i+y_offset)  > 2) &&  ((i+y_offset)  < 3 + (4 *MODES_NUMBER_OF_TIMERS)  ) ){
        byte timer = ((i+y_offset) - 3)  / 4 ;
        byte offset = ((i+y_offset) - 3)  % 4 ;

        if (offset == 0 ){
          strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  5 ]     )));
          lcd.print(buffer );
          lcd.print((int)timer+1);
          strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  6 ]     )));
          lcd.print(buffer );
          if (Mode_Timer_On[timer] == false){
            Print_OFF();
          } 
          else {
            Print_ON();
          }
        }
        else if ( offset == 1 ) {
          strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  7 ]     )));
          lcd.print(buffer );
          clock.print_time_min(Mode_Timer_HR[timer],Mode_Timer_MIN[timer]);
        } 
        else if (offset== 2 ){
          strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  8 ]     ))); //" Days:"
          lcd.print(buffer );
          for ( int day = 1 ; day < 8 ; ++day){
            if (  bitRead( Mode_Timer_DAY[timer], day )  ){
              strcpy_P(buffer, (char*)pgm_read_word(&(  short_days_names_table[ day -1 ]     )));
              lcd.print(buffer );
            }
            else{
              if( day != 7 ){
                Print_Space();  
              }
            }
          } 
        }
        else {
          Print_Space();
          strcpy_P(buffer, (char*)pgm_read_word(&(  Mode_Set_Menu_table[  3 ]     )));
          lcd.print(buffer );
          aquarium_modes.Print(  Mode_Timer_MoveTo[timer]  );
        }
      }
    }
  }
}
















































































































































































































































